World Environment
-
WorldEnvironment: 3D Lighting Setup .
-
In Godot 4 it is no longer possible to change the color of the 'Projected Shadow' in 'DirectionalLight'.
-
-
Lighting Setup: WorldEnvironment + DirectionalLight :
-
Sky:
-
'PanoramaSkyMaterial':
-
As objects are lit by the Sky indiscriminately, having a dark 'ground' to symbolize the floor is useful to make the underside of objects darker. However, if the character reaches a very high altitude, they may be able to see the ground on the horizon. If that happens, the HDRI can be edited in Photoshop, requiring some adjustment in 'AmbientLight' to counterbalance the loss of contrast in shadows.
-
-
'ProceduralSkyMaterial':
-
'Sun':
-
The 'DirectionalLight3D' node controls the Sun's 'latitude' and 'longitude' by its rotation angle in the scene.
-
'AngleMax':
-
Affects the size of all Suns in the scene.
-
Increasing the Sun size can affect the brightness of objects in the scene.
-
-
-
-
-
ToneMap:
-
"Transformation from 'linear colorspace' to 'sRGB colorspace'".
-
Exposure:
-
Affects everything in the world and the Sky itself, mostly affecting the bright parts, that is, it does not affect shadows that much. However, it is mostly used to calibrate the level of detail and brightness of the Sky.
-
-
White:
-
Affects a bit of the entire exposure, but mostly the 'upper end of the exposure range'.
-
-
-
Ambient Light:
-
Considered as the "Fill Light" or "secondary light".
-
Can be used to calibrate the color of 'Projected Shadows and Self-shadows' and everything else, mostly affecting the shadows, without affecting the Sky.
-
Color:
-
Color of the light.
-
-
Energy:
-
Affects the 'energy' of the light, making the 'Projected Shadows and Self-shadows' weaker or stronger.
-
-
Sky Contribution:
-
Percentage of the 'Sky' contribution to the 'AmbientLight'.
-
Reducing 'Sky Contribution' makes the AmbientLight's light stand out, so if the slider is zeroed, the 'Sky' will have no contribution.
-
-
-
DirectionalLight:
-
~Considered the "primary light".
-
Can be used to calibrate the color of everything except the shadows, without affecting the Sky; this implies using 'Ambient Light' to calibrate only the shadows while the 'DirectionalLight' handles the rest.
-
Care should be taken with the amount of color put into the DirectionalLight, since it easily becomes oversaturated.
-
It is useful to align the DirectionalLight direction with the "sun" direction in the Sky.
-
-
Global Illumination
-
*Note:
-
There is a folder in [Attachments/Global Illumination] with comparison photos.
-
-
Global Illumination: Introduction and technique comparison .
-
Global Illumination: LightmapGI .
-
You must select the meshes and create a UV2 for each; if not done, the mesh will be ignored in the bake, receiving no light or shadow.
-
The docs explain the following options:
-
Mark the 'Light Baking -> Static Lightmaps' option when importing the Mesh; Godot recommends this.
-
[4.3-dev5] This does nothing for an Inherited Scene...
-
-
'Unwrap UV2 for Lightmap/AO' when selecting the Mesh.
-
Via Blender, by generating an extra UV; Godot does not recommend this.
-
-
Note: do not ignore
.unwrap_cachefiles in git.
-
-
Does not update at runtime, as it is completely static.
-
Does not bake reflections, so LightmapGI is usually used together with ReflectionProbe for better quality.
-
Has fewer light bleeding issues compared to VoxelGI and SDFGI.
-
It is the oldest and slowest baking technique but gives the best quality and performance if the scene is fully static.
-
Also, both options provide the best mobile and old PC compatibility.
-
-
The difference between Medium and High is extremely subtle, almost imperceptible.
-
-
Global Illumination: ReflectionProbe .
-
Gives a very good effect. Works well when combined with LightmapGI.
-
"To get reasonably accurate reflections, you should generally have one ReflectionProbe node per room (sometimes more for large rooms)."
-
"This essentially acts as local ambient lighting."
-
Can be real-time if 'Update Mode -> Always' is enabled.
-
-
Global Illumination: VoxelGI .
-
Only bakes Indirect Light, meaning it does not produce Light or Shadow.
-
Did not work on 'plane' meshes, so I had to convert the 'plane' into a 'box'.
-
The options inside Data were useful to calibrate the final result.
-
In general, I did not like the result much, but adjusting Subdivisions and Propagation helped. Still, LightmapGI + Reflection Probes were superior.
-
-
Global Illumination: Creating a Fake Global Illumination .
-
Based on duplicating the light, rotating it, and reducing its "strength".
-
Can be done with DirectionalLight or OmniLight.
-
I tested it with DirectionalLight and it looked good.
-
Only makes sense if not using another GI technique.
-
Light Equation
shader_type spatial;
void light() {
// light we wish to accumulate
DIFFUSE_LIGHT += ALBEDO * ATTENUATION * LIGHT_COLOR * max(dot(LIGHT,NORMAL), 0.0);
// assign the result
SPECULAR_LIGHT = round(DIFFUSE_LIGHT*16.0 - 0.5)/16.0; // posterizes the final color
//SPECULAR_LIGHT = DIFFUSE_LIGHT; // do nothing to the result
// cancel all contribution of the diffuse_light variable
SPECULAR_LIGHT -= ALBEDO * DIFFUSE_LIGHT;
}
-
Diffuse Lambert:
-
This is just my interpretation at the time.
-
float NdotL = min(1.0, dot(NORMAL, LIGHT));
float cNdotL = max(NdotL, 0.0);
float diffuse_brdf_NL = cNdotL / PI; // For 'lambert'
DIFFUSE_LIGHT += LIGHT_COLOR * ATTENUATION * diffuse_brdf_NL;
Light2D
-
About Z_Index and Layer:
-
As far as I understand, the light and the shadow generated by Light2D and LightOccluder2D do not care about Z_Index, only Layer and Mask. This suggests that both are not "objects", but rather "Areas" or "Drawings".
-
However, both can interact with CanvasLayer, despite not interacting with Z_Index within the Canvas.
-
-
' Range ItemCull_Mask':
-
The "Range" mask determines which layer receives light.
-
-
' Shadow ItemCull_Mask':
-
The "Shadow" mask determines which layer receives shadow.
-
Light3D
-
"'Light3D/Cull Mask' is the layers which the light affects, 'VisualInstance/Layers' affects which cameras can see this light."
Shadows
-
Lighting: How to make shadows (behind the Sprite) in 2D (4.x) .
-
Lighting: How to make shadows (behind the Sprite) in 2D (3.x) .
-
Lighting: Light2D and Day&Night Cycle (bad solution for self-shadowing) .
-
Lighting: Examples of Light and Shadow + Normal Maps with Laigter .
-
Lighting: Show an object only in Light; tips to create shadows using tilemap .
-
The video is very nice and simple.
-
Light Only is used to show the enemy only in shadows.
-
A generic tilemap with occluder is used to quickly generate shadows; this is very cool and useful.
-
LightOccluder2D
-
'Closed':
-
I don't see any use in changing this; I did not find an effect that benefits from this property.
-
-
'Cull Mode':
-
'Clockwise', 'CounterClockwise'. If you are making a Platformer2D or FullTopDown2D style game, 'Cull Mode' can be very useful to make shadows that interact correctly with the object.
-
-
'SDF Collision':
-
"If enabled, the occluder will be part of a real-time generated 'signed distance field' that can be used in custom shaders. When not using custom shaders that read from this SDF, enabling this makes no visual difference and has no performance cost, so this is enabled by default for convenience."
-
-
'OccluderLight_Mask':
-
"This is used in tandem with PointLight2D and DirectionalLight2D's 'Shadow > Item Cull Mask' property to control which objects cast shadows for each light. This can be used to prevent specific objects from casting shadows."
-
Making Shadows appear behind the Sprite
-
Godot documentation (Does not work):
-
LightOccluder2Ds follows the usual 2D drawing order. This is important for 2D lighting, as this is how you control whether the occluder should occlude the sprite itself or not.
-
If the LightOccluder2D node is a 'sibling' of the sprite, the occluder will occlude the sprite itself if it's placed 'below' the sprite in the scene tree. If the LightOccluder2D node is a 'child' of the sprite, the occluder will occlude the sprite itself if 'Show Behind Parent' is disabled on the LightOccluder2D node (which is the default).
-
(2024-10-26) I tested changing the position of the LightOccluder relative to the Sprite, testing using and not using Show Behind Parent, etc. It did not work.
-
-
Solution I use:
-
Separate the '
Light_Masks' and 'ItemCull_Masks' to be different for the Shadows and for the object's lighting, causing the Shadow not to be "drawn" in front of the sprite. -
(2024-10-26) I did not understand this explanation. I have to test.
-
OccluderInstance3D
-
An
Occluder'of opaque objects of sibling Nodes can be created by clicking 'Bake Occluder', or an Occluder can be created manually. -
The
Occluderwill only work ifOcclusionCullingis enabled in ProjectSettings. -
~When enabled, the Occluder will block the visualization of the object under certain conditions. The effect reminded me of Minecraft chunk loading.